from client import es_client
from client.es_client import ESResponseWrapper
from client.redis_client import r
from model.es.card import ElectronicCardModel
from model.wristband_models import LocationData, HealthData
from utils.date_utils import timestamp_to_str_000z
from utils.logger_util import logger


async def update_card_step(imei: str, step: int):
    es_doc_id = r.hget('card', imei)
    updated_fields = {
        "step": step,
    }
    await update_doc_by_id('p_electron_card', es_doc_id, updated_fields)
    logger.info(f'更新步数imei{imei}card表id{es_doc_id}更新值为{updated_fields}')


async def update_battery(battery: int, _id: str):
    updated_fields = {
        "battery": battery,
    }
    await update_doc_by_id('p_electron_card', _id, updated_fields)
    # logger.info(f'更新电量，imei{imei}，card_id{es_doc_id}，更新值为{updated_fields}')


async def update_health(health: HealthData):
    # 初始化 Elasticsearch 客户端
    # 要更新的字段及其新值
    es_doc_id = r.hget('card', health.device_id)
    health_fields = {}
    if health.blood_oxygen > 0:
        health_fields["bloodOxygen"] = health.blood_oxygen
    if health.blood_pressure_low > 0 and health.blood_pressure_high > 0:
        health_fields["bloodPressureLow"] = health.blood_pressure_low
        health_fields["bloodPressureHigh"] = health.blood_pressure_high
    if health.body_temperature > 0:
        health_fields["bodyTemperature"] = float(health.body_temperature)
    if health.heart_rate > 0:
        health_fields["heartRate"] = health.heart_rate
    await update_doc_by_id('p_electron_card', es_doc_id, health_fields)


async def update_card_location(location: LocationData, es_doc_id: str = None):
    # 初始化 Elasticsearch 客户端
    # 要更新的字段及其新值
    if es_doc_id is None:
        es_doc_id = r.hget('card', location.device_id)
    updated_fields = {
        "lat": str(location.latitude),
        "lon": str(location.longitude)
    }
    await update_doc_by_id('p_electron_card', es_doc_id, updated_fields)


async def update_card_wearing(wearing, _id: str):
    # 初始化 Elasticsearch 客户端
    # 要更新的字段及其新值
    updated_fields = {
        "wearing": wearing
    }
    await update_doc_by_id('p_electron_card', _id, updated_fields)


async def update_doc_by_id(index: str, es_doc_id, updated_fields):
    es = await es_client.get_es_client()
    try:
        # 直接通过 _id 更新文档
        await es.update(
            index,
            es_doc_id,
            {
                "doc": updated_fields
            }
        )
        # logger.info(f'更新文档成功{index}，文档编号{es_doc_id}，更新内容{updated_fields}')
    except Exception as e:
        logger.error(f'发生异常{e}')


async def get_doc_by_imei(imei: str):
    es = await es_client.get_es_client()
    query = {
        "query": {
            "bool": {
                "must": [
                    {"terms": {"imei": [imei]}}
                ],
                "must_not": [
                    {"term": {"state": {"value": 0}}}
                ]
            }
        }
    }
    results = await es.search(
        index="p_electron_card",
        query=query
    )
    card = ESResponseWrapper(results, model_cls=ElectronicCardModel)
    model = card.to_models()
    if len(model) > 0:
        return model[0]
    return None


async def find_imei(data: dict):
    query = {
        "size": 0,
        "query": {
            "bool": {
                "must": [{
                    "term": {
                        "deviceType": 2

                    }
                }, {
                    "term": {
                        "projectId": data['projectId']
                    }
                }]
            }
        },
        "aggs": {
            "imeis": {
                "terms": {
                    "field": "imei",
                    "size": 10000
                }
            }
        }
    }
    es = await es_client.get_es_client()
    result = await es.search(index='p_electron_card', query=query)
    imei_array = [item['key'] for item in result['aggregations']['imeis']['buckets']]
    return imei_array


# 写一个根据文档id查询文档的方法,并直接解析出 source index=p_electron_card
async def get_doc_by_id(index: str, es_doc_id: str):
    """
    根据索引和文档ID从Elasticsearch中获取文档。

    :param index: 索引名称
    :param es_doc_id: 文档ID
    :return: 获取到的文档
    """
    try:
        es = await es_client.get_es_client()
    except Exception as e:
        raise ConnectionError(f"Failed to get Elasticsearch client: {e}")

    if not index or not es_doc_id:
        raise ValueError("Index and es_doc_id must not be empty")

    try:
        return await es.get_document_has_id(index=index, doc_id=es_doc_id)
    except Exception as e:
        raise RuntimeError(f"Failed to get document: {e}")


async def get_card(device_id) -> ElectronicCardModel:
    try:
        return await get_doc_by_imei(device_id)
    except Exception as e:
        logger.error(f"Error  handling location data: {str(e)}")


async def get_card_list(term: dict):
    query = {
        "size": 200,
        "_source": ["imei", "age", "sex", "jobPost", "jobDutyName", "nickName", "departName", "member"],
        "query": {
            "bool": {
                "must": [
                    {"term": {"deviceType": 2}},
                    {"term": {"state": 1}},
                    {"term": term}
                ],
                "must_not": [
                    {"term": {"validState": 0}}
                ]
            }
        }
    }
    es = await es_client.get_es_client()
    return await es.search_documents(index='p_electron_card', query=query)


# 根据特定条件查询员工设备信息
async def get_card_list_customer(query_bool: dict):
    query = {
        "size": 200,
        "_source": ["imei", "age", "sex", "jobPost", "jobDutyName", "nickName", "departName", "member"],
        "query": {
            "bool": query_bool
        }
    }
    es = await es_client.get_es_client()
    return await es.search_documents(index='p_electron_card', query=query)


async def update_online_status(timestamp: int, _id: str):
    updated_fields = {
        "ctm": timestamp_to_str_000z(timestamp),
    }
    await update_doc_by_id('p_electron_card', _id, updated_fields)
